<template>
  <div class="paste-editor-wrapper">
    <textarea ref="codemirror" class="textarea-el"></textarea>
  </div>
</template>
<script>
  import CodeMirror from 'codemirror'
  import 'codemirror/lib/codemirror.css'
  import { forEach } from '@/libs/tools'
  import createPlaceholder from './plugins/placeholder'

  export default {
    name: 'PasteEditor',
    props: {
      value: Array,
      pasteData: {
        type: String,
        default: ''
      },
      placeholder: {
        type: String,
        default: '从网页或其他应用软件复制表格数据，粘贴到这里 。默认第一行是表头，使用回车键添加新行，使用Tab键区分列。'
      }
    },
    data () {
      return {
        pasteDataArr: [],
        rowArrLength: 0,
        editor: null
      }
    },
    watch: {
      pasteData (val) {
        if (val === '') {
          this.editor.setValue('')
        }
      }
    },
    computed: {
      rowNum () {
        return this.pasteDataArr.length
      },
      colNum () {
        return this.pasteDataArr[0] ? this.pasteDataArr[0].length : 0
      }
    },
    methods: {
      handleKeyup (e) {
        this.handleAreaData()
      },
      /**
       * @description 处理粘贴操作
       */
      handleContentChanged (content) {
        let pasteData = content.trim()
        this.$emit('on-content-change', pasteData)
        let rows = pasteData.split((/[\n\u0085\u2028\u2029]|\r\n?/g)).map(row => {
          return row.split('\t')
        })
        if (content === '') rows = []
        this.pasteDataArr = rows
        this.clearLineClass()
        this.checkColNumInEveryRow()
        this.$emit('input', this.pasteDataArr)
      },
      /**
       * @description 检查除第一行的每一行列数是否与第一行相同
       */
      checkColNumInEveryRow () {
        let i = 0
        const len = this.rowNum
        if (len === 0) return
        while (++i < len) {
          let item = this.pasteDataArr[i]
          if (item.length !== this.colNum && (!(i === len - 1 && item.length === 1 && item[0] === '') || i !== len - 1)) {
            this.markIncorrectRow(i)
            this.$emit('on-error', i)
            return false
          }
        }
        this.$emit('on-success', this.pasteDataArr)
        return true
      },
      /**
       * @description 标记不符合格式的一行
       */
      markIncorrectRow (index) {
        this.editor.addLineClass(index, 'text', 'incorrect-row')
      },
      /**
       * @description 标记不符合格式的一行
       */
      clearLineClass () {
        forEach(this.pasteDataArr, (item, index) => {
          this.editor.removeLineClass(index, 'text', 'incorrect-row')
        })
      }
    },
    mounted () {
      createPlaceholder(CodeMirror)
      this.editor = CodeMirror.fromTextArea(this.$refs.codemirror, {
        lineNumbers: true,
        tabSize: 1,
        lineWrapping: true,
        placeholder: this.placeholder
      })
      this.editor.on('change', (editor) => {
        this.handleContentChanged(editor.getValue())
      })
      this.editor.addLineClass(0, 'text', 'first-row')
    }
  }
</script>
<style lang="less">
  @import './paste-editor.less';
</style>
